
package jp.co.brilliantservice.app.sos;

import java.util.Date;
import java.util.List;

import jp.co.brilliantservice.app.sos.CellLocationAsyncTask.onPosteExecuteListener;
import jp.co.brilliantservice.app.sos.TwitterAsyncTask.onPostedListener;
import twitter4j.http.AccessToken;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

public class TwitterService extends Service implements LocationListener {

    private static final String ACCESS_TOKEN = "265281923-9bHBExcCppVnJUYGc5GRE1X6xwfEvQCj0vuVeSvE";
    private static final String ACCESS_SECRET = "28d6TJCzxIra74C1Ws5cw8Whm2CKdW1rlrZvFNLcrI";

    private Context mContext;
    private static LocationManager mgr = null;
    private static int badAccuracyCount = 0;
    private static String mText;
    private static String mTarget;
    private SettingManager mPref;
    private long mTriggerTime = 0;
    private long mTimeoutTime = 0;
    private PendingIntent alarmIntent = null;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        mPref = new SettingManager(mContext);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        if (mgr == null) {
            mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
        }
        String action = intent.getStringExtra("action");
        if (action != null && action.equalsIgnoreCase("timeout")) {
            mgr.removeUpdates(this);
            badAccuracyCount = 0;
            // タイムアウトしたのでセル測位を開始する
            startGetCellLocation();
        } else {
            mText = intent.getStringExtra("text");
            startGetLocation();
        }
    }

    private void startGetLocation() {
        Date now = new Date();
        Criteria criteria = new Criteria();
        String best = mgr.getBestProvider(criteria, true);
        List<String> all = mgr.getProviders(true);
        if (all.contains(LocationManager.GPS_PROVIDER)) {
            best = LocationManager.GPS_PROVIDER;
        }
        if (best != null) {
            // 15秒のタイムアウトを設定
            setTimeoutTimer(now.getTime() + 15000);
            mgr.requestLocationUpdates(best, 0, 0, this);
        } else {
            /* ロケーション取得できないので3分後に起動 */
        }
    }

    private void startTweet(String target, String text) {
        AccessToken accessToken;
        SettingManager pref = new SettingManager(mContext);
        String token = pref.get("token");
        String tokenSecret = pref.get("tokenSecret");
        if(TextUtils.isEmpty(token) || TextUtils.isEmpty(tokenSecret)){
            token = ACCESS_TOKEN;
            tokenSecret = ACCESS_SECRET;
        }
        if (token.length() > 0 && tokenSecret.length() > 0) {
            accessToken = new AccessToken(token, tokenSecret);
            if (accessToken != null) {
                TwitterAsyncTask task = new TwitterAsyncTask(mContext, accessToken, true);
                task.setOnPostedListener(new onPostedListener() {
                    @Override
                    public void onPosted(boolean success) {
                        if (success) {
//                            Toast.makeText(mContext, "成功しました", Toast.LENGTH_SHORT).show();
                        } else {
//                            Toast.makeText(mContext, "失敗しました", Toast.LENGTH_SHORT).show();
                        }
                        stopSelf();
                    }
                });
                if (target != null && target.length() > 0) {
                    task.execute(TwitterAsyncTask.SEND_DIRECTMESSAGE
                            , target
                            , text);
                    Toast.makeText(mContext, target + "に「" + text + "」のダイレクトメッセージを送信中",
                            Toast.LENGTH_SHORT).show();
                } else {
                    task.execute(TwitterAsyncTask.POST
                            , text);
                    Toast.makeText(mContext, "「" + text + "」をつぶやき中", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.e("**********", "lat=" + location.getLatitude() + " lng=" + location.getLongitude()
                + "accuracy=" + location.getAccuracy());
        if (location.getAccuracy() > 500) {
            /* 精度が悪い場合は何もしない */
            // TODO 精度が悪いときはMyLocationOverlayを使う？
            badAccuracyCount++;
            if (badAccuracyCount >= 10) {
                /* アップデートを止める */
                mgr.removeUpdates(this);
                badAccuracyCount = 0;
            }
        } else {
            cancelTimeoutTimer();
            mgr.removeUpdates(this);
            badAccuracyCount = 0;
            tweetWithLocation(location);
        }
    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    private void setTimeoutTimer(long triggerTime) {
        mTimeoutTime = triggerTime;
        setRtcAlarm(triggerTime);
    }

    private void cancelTimeoutTimer() {
        if (alarmIntent != null && mTriggerTime == mTimeoutTime) {
            /* 以前のアラームをキャンセル */
            ((AlarmManager) getSystemService(ALARM_SERVICE)).cancel(alarmIntent);
            alarmIntent = null;
            mTriggerTime = 0;
        }
        mTimeoutTime = 0;
    }

    private void setRtcAlarm(long triggerTime) {
        Date now = new Date();
        if (mTriggerTime == 0
                || ((mTriggerTime > 0) && mTriggerTime > triggerTime)
                || (mTriggerTime <= now.getTime() && triggerTime > now.getTime())) {
            mTriggerTime = triggerTime;
            if (alarmIntent != null) {
                /* 以前のアラームをキャンセル */
                ((AlarmManager) getSystemService(ALARM_SERVICE)).cancel(alarmIntent);
            }
            Intent intent = new Intent(this, TimerReceiver.class);
            intent.putExtra("action", "timeout");
            /* RTCアラームを設定 */
            alarmIntent = PendingIntent.getBroadcast(
                    this
                    , 0
                    , intent
                    , 0);
            ((AlarmManager) getSystemService(ALARM_SERVICE)).set(
                    AlarmManager.RTC_WAKEUP
                    , triggerTime
                    , alarmIntent
                    );
            {
                Date rtcDate = new Date();
                rtcDate.setTime(mTriggerTime);
            }
        }
    }

    private void startGetCellLocation() {
        CellLocationAsyncTask task = new CellLocationAsyncTask(mContext, true);
        task.setOnPostedExecuteListener(new onPosteExecuteListener() {
            @Override
            public void onPosteExecute(Location location) {
                tweetWithLocation(location);
            }
        });
        task.execute();
    }

    private void tweetWithLocation(Location location) {
        if (location!=null) {
            StringBuilder builder = new StringBuilder();
            builder.append(mText);
            builder.append(" http://maps.google.co.jp/?q=");
            builder.append(location.getLatitude());
            builder.append(",");
            builder.append(location.getLongitude());
            builder.append(" ");
            builder.append("#");
            builder.append(mPref.get("hashtag"));
            startTweet(mTarget, builder.toString());
        }
    }
}
